package com.feather.tenia.mysql;

import com.feather.common.data.DataTable;
import com.feather.common.db.Connector;
import com.feather.tenia.adapter.TeniaAdapter;
import com.feather.tenia.mysql.fetcher.CURSOR_Fetcher;
import com.feather.tenia.JdbcProperty;
import com.feather.tenia.Procedure;
import com.feather.tenia.ProcedureMeta;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.List;

/**
 * @author flogyin
 */
public class MysqlTenia extends TeniaAdapter {
	protected CURSOR_Fetcher	cursorFetcher;

	public MysqlTenia(Connector connector, JdbcProperty jdbcProperty) {
		super(connector, jdbcProperty);
		this.cursorFetcher = new CURSOR_Fetcher(this);

		mapSqlType("mediumint", Types.INTEGER);
		mapSqlType("year", Types.DATE);
		mapSqlType("tinyblob", Types.BLOB);
		mapSqlType("mediumblob", Types.BLOB);
		mapSqlType("longblob", Types.BLOB);
		mapSqlType("varbinary", Types.BLOB);
		mapSqlType("tinytext", Types.CLOB);
		mapSqlType("text", Types.CLOB);
		mapSqlType("mediumtext", Types.CLOB);
		mapSqlType("longtext", Types.CLOB);
	}

	@Override
	public Procedure getProcedure(String procName) throws SQLException {
		Procedure procedure = super.procedureCache.get(procName);
		if (procedure == null) {
			ProcedureMeta meta = this.createProcedureMeta(procName);
			List<ProcedureMeta> metaList = super.listProcedure(meta.getCatalog(), meta.getSchema(), meta.getName());
			if (metaList.size() > 0) {
				meta = metaList.get(0);
				meta.setOriginal(procName);
				procedure = new MysqlProcedure(this, meta);
				if (isCacheProcedureColumn())
					super.procedureCache.put(procName, procedure);
			}
		}
		return procedure;
	}

	@Override
	public Procedure getProcedure(String catalog, String schema, String name) throws SQLException {
		String procName = catalog + "." + schema + "." + name;
		Procedure procedure = super.procedureCache.get(procName);
		if (procedure == null) {
			List<ProcedureMeta> metaList = super.listProcedure(catalog, schema, name);
			if (metaList.size() > 0) {
				ProcedureMeta meta = metaList.get(0);
				procedure = new MysqlProcedure(this, meta);
				if (isCacheProcedureColumn())
					super.procedureCache.put(procName, procedure);
			}
		}
		return procedure;
	}

	@Override
	protected void setCatalog() {
		// DB Name (insite url)
		String url = super.jdbcProperty.getURL();
		int dd = url.indexOf("//");
		if (dd != -1) {
			int at = url.indexOf("/", dd + 2);
			if (at != -1)
				super.catalog = url.substring(at + 1);
		}
	}

	@Override
	protected void setSchema() {

	}

	@Override
	protected ProcedureMeta createProcedureMeta() {
		return createProcedureMeta(super.catalog, super.schema, null);
	}

	@Override
	protected ProcedureMeta createProcedureMeta(String procName) {
		String catalog = getCatalog();// db
		ProcedureMeta meta = createProcedureMeta(catalog, super.schema, procName);
		meta.setOriginal(procName);
		return meta;
	}

	@Override
	protected ProcedureMeta createProcedureMeta(String catalog, String schema, String name) {
		MysqlProcedureMeta meta = new MysqlProcedureMeta();
		meta.setCatalog(catalog);
		meta.setSchema(schema);
		meta.setName(name);
		return meta;
	}

	@Override
	protected DataTable getDataTable(Statement statement, ResultSet resultSet) throws SQLException {
		DataTable dataTable = (DataTable) this.cursorFetcher.fetch(resultSet, null);
		return dataTable;
	}

	/*
	 * "float" "varchar" "tinyblob" "blob" "mediumblob" "longblob" "binary"
	 * "varbinary" "tinytext" "text" "mediumtext" "longtext" "real" "enum" "set"
	 */
}
